package com.tzl.design_pattern.prototype_pattern;

import java.util.Arrays;

/**
 * 原型模式:<br>
 * 是指原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象,调用者不需要知道任何创建细节,不调用构造函数,原型模式属于创造型模式.<br>
 * 深克隆带来的问题:<br>
 * 会破坏单例对象,所以如果是单例对象我们可以通过两个办法防止破坏:<br>
 * 1. 不实现Cloneable接口,使得该类不支持克隆<br>
 * 2. 重写clone()方法,并且返回单例对象<br>
 * 适用场景:<br>
 * 1. 类初始化消耗资源较多时;<br>
 * 2. 初始化一个对象时需要非常繁琐的过程时;<br>
 * 3. 构造函数比较复杂时;<br>
 * 4. 循环体中生产大量对象时,可读性下降时<br>
 * 优点:<br>
 * 1. 当创建一个对象比较复杂时,使用原型对象通常效率会更高.<br>
 * 缺点:<br>
 * 1. 需要为每个对象配备克隆或可拷贝的方法<br>
 * 2. 对克隆复杂对象或者对克隆出来的对象进行复杂改造时,易带来风险,深克隆,浅克隆要运用得当<br>
 *
 * @author Zhilei Tang
 * @date Created in 2020/11/15 13:53
 */
public class PrototypeTest {
  public static void main(String[] args) throws CloneNotSupportedException {
    PrototypeImpl_A implA = new PrototypeImpl_A();
    implA.setName("张三");
    implA.setAge(23);
    implA.setPhoneList(Arrays.asList("12345", "4324324", "4324324", "5677556"));
    PrototypeImpl_A clone = (PrototypeImpl_A) implA.clone();
    System.out.println(implA.getPhoneList() == clone.getPhoneList()); // true,因为这种克隆方式是浅克隆

    Prototype_B prototypeB = new Prototype_B();
    prototypeB.setAge(23);
    prototypeB.setName("张三");
    prototypeB.setPhoneList(Arrays.asList("12345", "4324324", "4324324", "5677556"));
    Prototype_B clone1 = (Prototype_B) prototypeB.clone();
    System.out.println(prototypeB.getPhoneList() == clone1.getPhoneList()); // false,深拷贝
  }
}
